import subprocess
from pathlib import Path
import xml.etree.ElementTree as et

name_cn_dict = {
    "AppUp.IntelGraphicsExperience": "英特尔显卡控制中心",
    "Clipchamp.Clipchamp": "Clipchamp视频编辑器",
    "Microsoft.3DBuilder": "3D建模",
    "Microsoft.549981C3F5F10": "Cortana",
    "Microsoft.BingNews": "资讯",
    "Microsoft.BingWeather": "天气",
    "Microsoft.GamingApp": "Xbox",
    "Microsoft.GetHelp": "获取帮助",
    "Microsoft.Getstarted": "Microsoft 使用技巧",
    "Microsoft.HEIFImageExtension": "HEIF图片扩展",
    "Microsoft.HEVCVideoExtension": "HEVC视频扩展",
    "Microsoft.Ink.Handwriting.Main.zh-Hans.1.0": "墨迹手写识别语言包",
    "Microsoft.Ink.Handwriting.zh-Hans.1.0": "墨迹手写识别语言包",
    "Microsoft.LanguageExperiencePackzh-CN": "中文(简体)本地体验包",
    "Microsoft.Messaging": "消息",
    "Microsoft.Microsoft3DViewer": "3D查看器",
    "Microsoft.MicrosoftEdge.Stable": "Edge浏览器稳定版",
    "Microsoft.MicrosoftOfficeHub": "Office Hub",
    "Microsoft.MicrosoftSolitaireCollection": "微软纸牌游戏合集",
    "Microsoft.MicrosoftStickyNotes": "便签",
    "Microsoft.MixedReality.Portal": "混合现实门户",
    "Microsoft.MSPaint": "画图",
    "Microsoft.Office.OneNote": "OneNote",
    "Microsoft.OneConnect": "OneConnect",
    "Microsoft.OutlookForWindows": "Outlook新",
    "Microsoft.Paint": "画图",
    "Microsoft.People": "人脉",
    "Microsoft.PowerAutomateDesktop": "PowerAutomate自动任务",
    "Microsoft.Print3D": "打印3D",
    "Microsoft.RawImageExtension": "Raw图像扩展",
    "Microsoft.ScreenSketch": "截图工具",
    "Microsoft.SkypeApp": "Skype应用",
    "Microsoft.StorePurchaseApp": "Store体验主机",
    "Microsoft.Todos": "Todos待办事项",
    "Microsoft.VP9VideoExtensions": "VP9视频扩展",
    "Microsoft.Wallet": "钱包",
    "Microsoft.WebMediaExtensions": "Web媒体扩展",
    "Microsoft.WebpImageExtension": "Webp 图像扩展",
    "Microsoft.Windows.Photos": "照片",
    "Microsoft.WindowsAlarms": "闹钟",
    "Microsoft.WindowsCalculator": "计算器",
    "Microsoft.WindowsCamera": "相机",
    "Microsoft.windowscommunicationsapps": "邮件和日历",
    "microsoft.windowscommunicationsapps": "邮件和日历",
    "Microsoft.WindowsFeedbackHub": "Windows反馈中心",
    "Microsoft.WindowsMaps": "地图",
    "Microsoft.WindowsNotepad": "记事本",
    "Microsoft.WindowsSoundRecorder": "录音机",
    "Microsoft.Xbox.TCUI": "Xbox Live",
    "Microsoft.XboxApp": "XboxApp",
    "Microsoft.XboxGameOverlay": "XboxGameBar",
    "Microsoft.XboxGamingOverlay": "XboxGamingOverlay",
    "Microsoft.XboxIdentityProvider": "Xbox身份提供者",
    "Microsoft.XboxSpeechToTextOverlay": "XboxSpeech",
    "Microsoft.YourPhone": "你的手机",
    "Microsoft.ZuneMusic": "Zune音乐",
    "Microsoft.ZuneVideo": "Zune视频",
    "MicrosoftCorporationII.MicrosoftFamily": "Family",
    "MicrosoftCorporationII.QuickAssist": "快速助手",
    "MicrosoftTeams": "Teams",
    "MSTeams": "Teams",
    "MicrosoftWindows.Client.WebExperience": "入门",
    "NVIDIACorp.NVIDIAControlPanel": "英伟达控制面板",
    "RealtekSemiconductorCorp.RealtekAudioControl": "Realtek音频控制",
    "Microsoft.MicrosoftPCManager": "微软电脑管家",
    "Microsoft.BingSearch": "必应搜索",
    "Microsoft.AV1VideoExtension": "AV1视频扩展",
    "Microsoft.ApplicationCompatibilityEnhancements": "应用程序兼容性增强",
    "Microsoft.MPEG2VideoExtension": "MPEG-2视频扩展",
    "Microsoft.AVCEncoderVideoExtension": "AVC编码器视频扩展",
    "BaiduNetdisk.DesktopSyncClient": "百度网盘桌面同步",
    "MicrosoftWindows.CrossDevice": "跨设备服务",
    "Microsoft.WindowsStore": "Windows商店",
    "Microsoft.Windows.DevHome": "DevHome",
    "Microsoft.WindowsTerminal": "Windows终端",
    "Microsoft.SecHealthUI": "Windows安全中心",
    # "": "",
}
recom_uninstall_list = [
    "Clipchamp.Clipchamp",
    "Microsoft.3DBuilder",
    "Microsoft.549981C3F5F10",
    "Microsoft.BingNews",
    "Microsoft.BingWeather",
    "Microsoft.GamingApp",
    "Microsoft.GetHelp",
    "Microsoft.Getstarted",
    "Microsoft.Messaging",
    "Microsoft.MicrosoftOfficeHub",
    "Microsoft.MicrosoftSolitaireCollection",
    "Microsoft.MixedReality.Portal",
    "Microsoft.Office.OneNote",
    "Microsoft.OneConnect",
    "Microsoft.OutlookForWindows",
    "Microsoft.People",
    "Microsoft.PowerAutomateDesktop",
    "Microsoft.Print3D",
    "Microsoft.SkypeApp",
    "Microsoft.Todos",
    "Microsoft.Wallet",
    "Microsoft.Windows.Photos",
    "Microsoft.WindowsAlarms",
    "Microsoft.WindowsCamera",
    "Microsoft.windowscommunicationsapps",
    "microsoft.windowscommunicationsapps",
    "Microsoft.WindowsMaps",
    "Microsoft.Xbox.TCUI",
    "Microsoft.XboxApp",
    "Microsoft.XboxGameOverlay",
    "Microsoft.XboxGamingOverlay",
    "Microsoft.XboxIdentityProvider",
    "Microsoft.XboxSpeechToTextOverlay",
    "Microsoft.YourPhone",
    "Microsoft.ZuneMusic",
    "Microsoft.ZuneVideo",
    "MicrosoftCorporationII.MicrosoftFamily",
    "MicrosoftCorporationII.QuickAssist",
    "MicrosoftTeams",
    "MSTeams",
    "Microsoft.MicrosoftPCManager",
]


class Appx:
    def __init__(self, name, is_framework, non_removable, signature_kind, pkg_name, install_location, version, id):
        self.name = name
        self.cn_name = name_cn_dict.get(name, name)
        self.is_framework = is_framework
        self.non_removable = non_removable
        self.signature_kind = signature_kind
        self.pkg_name = pkg_name
        self.install_location = install_location
        self.version = version
        self.canbe_uninstall = not non_removable
        self.id = f"{id:04}"

    def uninstall(self):
        uninstall(self)

    def is_installed(self):
        return is_installed(self.name)


def get_appxs():
    getapp_pscmd = "Get-AppxPackage | Select-Object -Property Name, IsFramework, NonRemovable, SignatureKind,PackageFullName,InstallLocation,Version"
    echo = ""
    try:
        echo = subprocess.run(["powershell", getapp_pscmd], capture_output=True, text=True)
        # print(echo.stdout)
        echo_list = list(filter(None, echo.stdout.split("\n\n")))
        # print(echo_list[1])
        appx_list = []
        id = 0
        for txt in echo_list:
            id += 1
            name, isFramework, nonRemovable, signatureKind, packageFullName, installLocation, version = ("",) * 7
            for line in txt.split("\n"):
                if line.startswith("Name"):
                    name = line.split(":")[1].strip()
                    # print(name)
                elif line.startswith("IsFramework"):
                    isFramework = line.split(":")[1].strip().lower() == "true"
                elif line.startswith("NonRemovable"):
                    nonRemovable = line.split(":")[1].strip().lower() == "true"
                    # canbe_uninstall = not nonRemovable
                elif line.startswith("SignatureKind"):
                    signatureKind = line.split(":")[1].strip()
                elif line.startswith("PackageFullName"):
                    packageFullName = line.split(":")[1].strip()
                elif line.startswith("InstallLocation"):
                    installLocation = line.split(" : ")[1].strip()
                elif line.startswith("Version"):
                    version = line.split(":")[1].strip()
            # 实例化Appx
            app = Appx(name, isFramework, nonRemovable, signatureKind, packageFullName, installLocation, version, id)
            appx_list.append(app)
        return appx_list
    except Exception as e:
        print(f"获取包信息时出现错误： {e}")
        return None


def is_installed(app_name):
    """
    检查Windows应用商店应用是否已安装。

    效率低，建议调用get_apps()进行批量比较
    apps = get_appxs()
    for XXX in YYY:
        is_installed = appname in [x.name for x in apps]

    参数:
    app_name (str): 应用的名称，用于查询。

    返回:
    bool: 如果应用已安装，返回True；否则返回False。
    """
    command = f"Get-AppxPackage -Name '{app_name}'"
    try:
        result = subprocess.run(["powershell", command], capture_output=True, text=True)
        if result.stdout.strip() != "":
            return True
        else:
            return False
    except Exception as e:
        print(f"出现错误： {e}")


def uninstall(app):
    try:
        uninstall_command = f"Remove-AppxPackage -Package '{app.pkg_name}'"
        result = subprocess.run(["powershell", uninstall_command], capture_output=True, text=True)
        if result.returncode == 0:
            print(f"卸载命令执行成功！{app.pkg_name}")
        else:
            print(f'命令执行失败{app.pkg_name}，参考：')
            print(result.stderr)
    except Exception as e:
        print(f"卸载应用时出现错误： {e}")


def get_names():
    return [x.name for x in get_appxs()]


class ProvisionedAppx:
    def __init__(self, name, pkg_name, version, arch):
        self.name = name
        self.cn_name = name_cn_dict.get(name)
        self.pkg_name = pkg_name
        self.version = version
        self.arch = arch

    def uninstall_provisioned(self):
        uninstall_provisioned(self)

    def is_installed(self):
        return is_installed(self.name)

    def install(self):
        installers = get_location_installers()
        if installers:
            for installer in installers:
                if installer.name == self.name:
                    installer.install()


def get_provisioned_appxs():
    cmd = "DISM /Online /Get-ProvisionedAppxPackages"
    echo = ""
    try:
        echo = subprocess.run(cmd, capture_output=True, text=True).stdout
    except Exception as e:
        print(f'无法获取预装应用列表, 错误信息:\n {e}')
    echo_list = echo.split('\n\n')
    filtered_echo_list = [txt for txt in echo_list if txt.startswith('显示名称')]

    p_appxs_list = []
    for txt_block in filtered_echo_list:
        lines = txt_block.split('\n')
        for line in lines:
            if line.startswith("显示名称"):
                name = line.split(":")[1].strip()
            elif line.startswith("版本"):
                version = line.split(":")[1].strip()
            elif line.startswith("体系结构"):
                arch = line.split(":")[1].strip()
            elif line.startswith("PackageName"):
                pkg_name = line.split(":")[1].strip()
        # 实例化pAppx
        p_appxs = ProvisionedAppx(name, pkg_name, version, arch)
        p_appxs_list.append(p_appxs)
    return p_appxs_list


def uninstall_provisioned(app):
    cmd1 = f"DISM /Online /Remove-ProvisionedAppxPackage /PackageName:{app.pkg_name}"
    cmd2 = f"Remove-AppxPackage -Package '{app.pkg_name}'"
    result = subprocess.run(cmd1, capture_output=True, text=True)
    result2 = subprocess.run(["powershell", "-Command", cmd2], capture_output=True, text=True)
    if result.returncode == 0:
        print(f'{app.name} 预装卸载成功')
    else:
        print(f'{app.name} 预装卸载失败!!! 参考信息:\n {result.stdout}')
    if result2.returncode == 0:
        print(f'{app.name} 用户卸载成功')
    else:
        print(f'{app.name} 用户卸载失败!!! 参考信息:\n {result2.stdout}')


class LocationInstaller:
    def __init__(self, name, xml_path, is_installed):
        self.name = name
        self.xml_path = xml_path
        self.is_installed = is_installed

    def install(self):
        install(self)

    def uninstall(self):
        uninstall(self)

    def is_installed(self):
        return is_installed(self.name)


def get_location_installers():
    apps = get_appxs()

    path = Path("C:/Program Files/WindowsApps/")
    app_folder = [folder for folder in path.iterdir() if
                  folder.is_dir() and '.' in folder.name and 'neutral' not in folder.name]
    location_installers = []
    for x in app_folder:
        xml_file = x / 'AppxManifest.xml'
        if xml_file.exists():
            root = et.parse(xml_file).getroot()
            namespace = root.tag.split('}')[0] + "}"
            appname = root.find(f"{namespace}Identity").get("Name").strip()
            if appname is not None:
                is_installed = appname in [x.name for x in apps]
                location_installer = LocationInstaller(appname, xml_file, is_installed)
                location_installers.append(location_installer)
        else:
            print(f"找不到文件 {xml_file}")
    return location_installers


def install(location_installer):
    regcmd = f'Add-AppxPackage -DisableDevelopmentMode -Register "{location_installer.xml_path}"'
    try:
        result = subprocess.run(["powershell", regcmd], capture_output=True, text=True)
        if result.returncode == 0:
            location_installer.is_installed = True
            print(f'{location_installer.name} 注册成功')
        else:
            print(f'{location_installer.name} 注册失败!!! 注册命令：')
            print(regcmd)
            print(f"参考信息:\n {result.stderr}")
    except Exception as e:
        print(f'{location_installer.name} 注册发生错误!!!  参考：\n {e}')

# appxs = get_appxs()
# provisioned_appxs = get_provisioned_appxs()
# location_installers = get_location_installers()

# appx_list = get_appxs()
# for app in appx_list:
#     print(type(app.signature_kind), "\t", app.signature_kind)

# appxs = get_appxs()
# for x in appxs:
#     if not x.is_framework and x.canbe_uninstall:
#         pass
#         # print(x.signature_kind,"\t",x.name)
#         if x.cn_name == None:
#             print(x.name, "\t", x.install_location)

# appxs = get_appxs()
# for x in appxs:
#     if "teams" in x.name.lower():
#         print(x.name)
#         x.uninstall()

# for x in get_appxs():
#     if x.name in recom_uninstall_list:
#         x.uninstall()
# print(x.name, "\t", x.cn_name)

# papps = get_provisioned_appxs()
# for x in papps:
#     if "Teams" in x.name:
#         print(x.name, "\t", x.cn_name, "\t", x.pkg_name)
# print(x.name, "\t", x.cn_name)
# if x.cn_name==None:
#     print(x.name, "\t",x.cn_name)

# apps = get_appxs()
# installers = get_location_installers()
# for ins in installers:
#     if ins.name not in [x.name for x in apps]:
#         print("未安装\t", ins.name)
#         install(ins)


# location_installers = get_location_installers()
# for x in location_installers:
#     if "xbox" in x.name.lower():
#         x.install()

#     if x.name.lower().startswith('xbox'):
#         install(x)
#         print(x.is_installed)
#         print(x.name, x.is_installed)

# appxs = get_appxs()
# for x in appxs:
#     if x.name.startswith("Microsoft.ZuneMusic"):
#         print(x.version)
#         print(x.install_location)
# print(x.install_location)

# location_installers = get_location_installers()
# provisioned_appxs = get_provisioned_appxs()

# appxs = get_appxs()
# print(get_names())

# provisioned_appxs=get_provisioned_appxs()
# for x in provisioned_appxs:
#     print(x.is_installed(), x.name)
# print(f"{x.name} \t {x.pkg_name} \t {x.version} \t {x.arch}")

# for x in appxs:
#     print(f"{x.name} \t {x.isFramework} \t {x.nonRemovable} \t {x.signatureKind} \t {x.packageFullName}")


# print(is_installed("Microsoft.ScreenSketch"))
# uninstall("Microsoft.Paint_11.2404.1020.0_x64__8wekyb3d8bbwe")
# print(is_installed("Microsoft.Paint"))
